#[cfg(test)]
mod tests {
    use std::{
        panic,
        sync::{atomic::Ordering, Arc},
        time::Duration,
    };

    use tokio::{io::AsyncWriteExt, net::TcpSocket, time::sleep};

    use crate::{
        listener::{conf::ListenerConf, ListenerManager},
        runtime::{RuntimeManager, PROCESS_EXIT},
        stream::Stream,
    };

    #[test]
    fn test_listener() {
        // 测试框架会将worker runtime中的panic信息捕获.
        fn custom_panic_handler(info: &panic::PanicHookInfo) {
            if let Some(location) = info.location() {
                println!(
                    "real panic in {}:{}",
                    location.file(),
                    location.line()
                );
                panic!("paniced");
            }
        }

        panic::set_hook(Box::new(custom_panic_handler));

        RuntimeManager::init_main_runtime(1);
        RuntimeManager::init_worker_runtime(None, 1);

        RuntimeManager::main_runtime_block_on(async {
            let mut conf = ListenerConf::default();
            conf.address = "127.0.0.1:6610".to_string();
            conf.validate().unwrap();

            ListenerManager::register_listener_by_conf(Arc::new(conf)).unwrap();
            ListenerManager::run();

            RuntimeManager::get_worker_runtime()
                .get_handle()
                .spawn(async {
                    let socket = TcpSocket::new_v4().unwrap();
                    let stream = socket
                        .connect("127.0.0.1:6610".parse().unwrap())
                        .await
                        .unwrap();

                    let mut s: Stream = stream.into();

                    s.shutdown().await.unwrap();

                    println!("stream {:#?} shutdown", s.unique_id());

                    PROCESS_EXIT.store(true, Ordering::Relaxed);
                });

            let mut exit = false;
            loop {
                if PROCESS_EXIT.load(Ordering::Relaxed) {
                    println!("process done");
                    exit = true;
                }

                sleep(Duration::from_millis(100)).await;
                if exit {
                    break;
                }
            }
        });
    }
}
